package com.talent.proxy.mysql.common.packets.s2c;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.talent.aio.common.ChannelContext;
import com.talent.aio.common.exception.AioDecodeException;
import com.talent.proxy.mysql.common.Capabilities;
import com.talent.proxy.mysql.common.MysqlExt;
import com.talent.proxy.mysql.common.MysqlPacket;
import com.talent.proxy.mysql.common.MysqlReturn;
import com.talent.proxy.mysql.common.StatusFlags;
import com.talent.proxy.mysql.common.json.Json;
import com.talent.proxy.mysql.common.packets.s2c.resultset.FieldMetaDataPacket;
import com.talent.proxy.mysql.common.packets.s2c.resultset.ResultSetHeaderPacket;
import com.talent.proxy.mysql.common.packets.s2c.resultset.RowDataPacket;
import com.talent.proxy.mysql.common.utils.DecodeUtils;

/**
 * 
 * @author tanyaowu 
 * @创建时间 2017年1月25日 下午9:21:14
 *
 * @操作列表
 *  编号	| 操作时间	| 操作人员	 | 操作说明
 *  (1) | 2017年1月25日 | tanyaowu | 新建类
 *
 */
public class ResultSetWithMetaPacket extends MysqlPacket
{
	private static Logger log = LoggerFactory.getLogger(ResultSetWithMetaPacket.class);
	
	private ResultSetHeaderPacket resultSetHeaderPacket = new ResultSetHeaderPacket();

	private List<FieldMetaDataPacket> fieldMetaDatas = new ArrayList<FieldMetaDataPacket>();

	private List<RowDataPacket> rowDatas = new ArrayList<RowDataPacket>();

	/**
	 * 
	 *
	 * @author: tanyaowu
	 * @创建时间:　2017年1月25日 下午9:21:14
	 * 
	 */
	public ResultSetWithMetaPacket()
	{

	}

	/**
	 * @param args
	 *
	 * @author: tanyaowu
	 * @创建时间:　2017年1月25日 下午9:21:14
	 * 
	 */
	public static void main(String[] args)
	{

	}

	/** 
	 * @see com.talent.proxy.mysql.common.MysqlPacket#bodySize()
	 * 
	 * @return
	 * @重写人: tanyaowu
	 * @重写时间: 2017年1月25日 下午9:21:29
	 * 
	 */
	@Override
	public int bodySize()
	{
		//不需要实现
		return 0;
	}

	/** 
	 * @see com.talent.proxy.mysql.common.MysqlPacket#packetDesc()
	 * 
	 * @return
	 * @重写人: tanyaowu
	 * @重写时间: 2017年1月25日 下午9:21:29
	 * 
	 */
	@Override
	protected String packetDesc()
	{
		return "resultset wiith meta data packet";
	}

	/** 
	 * @see com.talent.proxy.mysql.common.MysqlPacket#decodeBody(java.nio.ByteBuffer, com.talent.aio.common.ChannelContext)
	 * 
	 * @param buffer
	 * @param channelContext
	 * @return 
	 * @throws AioDecodeException
	 * @重写人: tanyaowu
	 * @重写时间: 2017年1月25日 下午9:21:29
	 * 
	 */
	@Override
	public MysqlPacket decode(ByteBuffer buffer, ChannelContext<MysqlExt, MysqlPacket, MysqlReturn> channelContext) throws AioDecodeException
	{
		MysqlExt mysqlExt = channelContext.getSessionContext();
		
		MysqlPacket mysqlPacket = DecodeUtils.dispatchDecode(buffer, channelContext, false);
		if (mysqlPacket != null)
		{
			return mysqlPacket;
		}
		
		resultSetHeaderPacket = (ResultSetHeaderPacket) resultSetHeaderPacket.decodeWithoutLog(buffer, channelContext);
		if (resultSetHeaderPacket == null)
		{
			return null;
		}

		//		List<FieldMetaDataPacket> fields = new ArrayList<FieldMetaDataPacket>();
		for (int i = 0; i < resultSetHeaderPacket.columnCount; i++)
		{
			FieldMetaDataPacket fp = new FieldMetaDataPacket();
			fp = (FieldMetaDataPacket) fp.decodeWithoutLog(buffer, channelContext);
			if (fp == null)
			{
				return null;
			}
			fieldMetaDatas.add(fp);
		}

		EOFPacket eofPacket = new EOFPacket();
		eofPacket = (EOFPacket) eofPacket.decodeWithoutLog(buffer, channelContext);
		
		if (eofPacket == null)
		{
			return null;
		}

		//		List<RowDataPacket> rowData = new ArrayList<RowDataPacket>();
		while (true)
		{
			int readableLength = buffer.limit() - buffer.position();
			if (readableLength < 4)
			{
				return null;
			}
			byte fieldCount = buffer.get(buffer.position() + 4);
			if (EOFPacket.MARK == fieldCount)
			{
				EOFPacket packet = new EOFPacket();
				packet = (EOFPacket) packet.decodeWithoutLog(buffer, channelContext);
				if (packet == null)
				{
					return null;
				}
				
				HandshakePacket handshakePacket = mysqlExt.getHandshakePacket();
				boolean checkForMoreResults = ((handshakePacket.capabilityFlags & Capabilities.CLIENT_MULTI_RESULTS) != 0);
				boolean hasMoreResults = (packet.status & StatusFlags.SERVER_MORE_RESULTS_EXISTS) != 0;
				if (checkForMoreResults && hasMoreResults)
				{
					//暂未实现
				}
				
				break;
			}

			RowDataPacket rowDataPacket = new RowDataPacket(resultSetHeaderPacket.columnCount);
			rowDataPacket = (RowDataPacket) rowDataPacket.decodeWithoutLog(buffer, channelContext);
			if (rowDataPacket == null)
			{
				return null;
			}
			rowDatas.add(rowDataPacket);
		}
		

		try
		{
			mysqlExt.getSeq().incrementAndGet();
			log.error("{} {}:{}", mysqlExt.getSeq().get(), this.getClass().getSimpleName(), Json.toJson(this));
		} catch (Exception e)
		{
			log.error(e.getMessage(), e);
		}
	
		return this;
	}

	/** 
	 * @see com.talent.proxy.mysql.common.MysqlPacket#encode(com.talent.aio.common.ChannelContext)
	 * 
	 * @param channelContext
	 * @return
	 * @重写人: tanyaowu
	 * @重写时间: 2017年1月25日 下午9:21:29
	 * 
	 */
	@Override
	public ByteBuffer encode(ChannelContext<MysqlExt, MysqlPacket, MysqlReturn> channelContext)
	{
		//不需要实现
		return null;
	}

	/** 
	 * @see com.talent.proxy.mysql.common.MysqlPacket#onReceived(com.talent.aio.common.ChannelContext)
	 * 
	 * @param channelContext
	 * @return
	 * @重写人: tanyaowu
	 * @重写时间: 2017年1月25日 下午9:21:29
	 * 
	 */
	@Override
	public MysqlReturn onReceived(ChannelContext<MysqlExt, MysqlPacket, MysqlReturn> channelContext)
	{
		return null;
	}

	/** 
	 * @see com.talent.proxy.mysql.common.MysqlPacket#decodeBody(java.nio.ByteBuffer, com.talent.aio.common.ChannelContext)
	 * 
	 * @param buffer
	 * @param channelContext
	 * @throws AioDecodeException
	 * @重写人: tanyaowu
	 * @重写时间: 2017年1月25日 下午9:39:16
	 * 
	 */
	@Override
	public void decodeBody(ByteBuffer buffer, ChannelContext<MysqlExt, MysqlPacket, MysqlReturn> channelContext) throws AioDecodeException
	{
		//不需要实现
	}

	/**
	 * @return the resultSetHeaderPacket
	 */
	public ResultSetHeaderPacket getResultSetHeaderPacket()
	{
		return resultSetHeaderPacket;
	}

	/**
	 * @param resultSetHeaderPacket the resultSetHeaderPacket to set
	 */
	public void setResultSetHeaderPacket(ResultSetHeaderPacket resultSetHeaderPacket)
	{
		this.resultSetHeaderPacket = resultSetHeaderPacket;
	}

	/**
	 * @return the fieldMetaDatas
	 */
	public List<FieldMetaDataPacket> getFieldMetaDatas()
	{
		return fieldMetaDatas;
	}

	/**
	 * @param fieldMetaDatas the fieldMetaDatas to set
	 */
	public void setFieldMetaDatas(List<FieldMetaDataPacket> fieldMetaDatas)
	{
		this.fieldMetaDatas = fieldMetaDatas;
	}

	/**
	 * @return the rowDatas
	 */
	public List<RowDataPacket> getRowDatas()
	{
		return rowDatas;
	}

	/**
	 * @param rowDatas the rowDatas to set
	 */
	public void setRowDatas(List<RowDataPacket> rowDatas)
	{
		this.rowDatas = rowDatas;
	}

}
